package com.yutel.phone.binh.data.net;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;

import android.util.Log;
import cn.com.xinli.android.service.protocol.BoxSearch;
import cn.com.xinli.android.service.protocol.BoxSearch.PinyinSearchResp;

import com.yutel.phone.binh.comm.StrUtil;
import com.yutel.phone.binh.data.BinhConfig;
import com.yutel.phone.binh.data.vo.Dict;
import com.yutel.phone.binh.data.vo.Keyword;
import com.yutel.phone.binh.data.vo.Pinyin;
import com.yutel.phone.binh.data.vo.SearchDict;
import com.yutel.phone.binh.data.vo.SearchKeyword;
import com.yutel.phone.binh.data.vo.SearchPinyin;

public class NetHelper {
	private static NetHelper netHelper;
	private final static String TAG = "NetHelper";
	private final static int connTimeOut = 20000;
	private final static int dataTimeOut = 60000;

	public static NetHelper getInstance() {
		if (netHelper == null) {
			netHelper = new NetHelper();
		}
		return netHelper;
	}

	private NetHelper() {
	}

	/**
	 * 数据字典
	 * 
	 * @param req
	 * @return
	 * @throws UnknownHostException
	 * @throws IOException
	 */
	public SearchDict searchDicALL(SearchDict req) throws UnknownHostException,
			IOException {
		Socket socketClient = null;
		SearchDict resp = null;
		DataInputStream dataInput = null;
		DataOutputStream dataOutput = null;
		try {
			socketClient = new Socket();
			socketClient.connect(new InetSocketAddress(BinhConfig.searchHost,
					BinhConfig.SearchPort), connTimeOut);
			socketClient.setSoTimeout(dataTimeOut);
			dataOutput = new DataOutputStream(socketClient.getOutputStream());
			BoxSearch.SearchDictReq.Builder builder = BoxSearch.SearchDictReq
					.newBuilder();
			builder.setAccount(req.getAcount());
			builder.setVersion(req.getVersion());
			BoxSearch.SearchDictReq searchDicReq = builder.build();
			dataOutput.writeInt(BoxSearch.SearchPacketType.DictReq.getNumber());
			dataOutput.writeInt(searchDicReq.getSerializedSize());// 传输序列化的字节长度
			dataOutput.write(searchDicReq.toByteArray());// 将发送内容转换为字节码数组
			dataOutput.flush();// 清空缓存

			dataInput = new DataInputStream(socketClient.getInputStream());
			int type = dataInput.readInt();// 获取返回值的长度
			int length = dataInput.readInt();
			byte dataini[] = new byte[length];// 设置长度
			dataInput.readFully(dataini);
			dataInput.close();
			socketClient.close();
			if (type == BoxSearch.SearchPacketType.SearchErr.getNumber()) {
				BoxSearch.SearchErrPacket response = BoxSearch.SearchErrPacket
						.parseFrom(dataini);
				Log.e(TAG, "response=" + response.getErrMsg());
				return null;
			}
			BoxSearch.SearchDictResp response = BoxSearch.SearchDictResp
					.parseFrom(dataini);
			if (response != null) {
				resp = new SearchDict();
				resp.setResultLeft(response.getResultLeft());
				resp.setDictType(response.getDictTypeCount());
				ArrayList<Dict> list = new ArrayList<Dict>();
				for (int i = 0; i < response.getDictCount(); i++) {
					BoxSearch.SearchDict dict = response.getDict(i);
					Dict vo = new Dict();
					vo.setNum(dict.getNum());
					vo.setType(dict.getType());
					vo.setValue(dict.getValue());
					list.add(vo);
				}
				resp.setList(list);
				return resp;
			}
		} catch (Exception e) {
			Log.e(TAG, "host:" + BinhConfig.searchHost + ","
					+ BinhConfig.SearchPort, e);
		} finally {
			closeSocket(socketClient, dataInput, dataOutput);
		}
		return resp;
	}

	/**
	 * 关键字查询
	 * 
	 * @param account
	 * @param channelid
	 * @param videoName
	 */
	public SearchKeyword KeywordSearch(SearchKeyword req) {
		Socket socketClient = null;
		SearchKeyword resp = null;
		DataOutputStream dataOutput = null;
		DataInputStream dataInput = null;
		try {
			socketClient = new Socket();
			socketClient.connect(new InetSocketAddress(BinhConfig.searchHost,
					BinhConfig.SearchPort), connTimeOut);
			socketClient.setSoTimeout(dataTimeOut);
			dataOutput = new DataOutputStream(socketClient.getOutputStream());
			BoxSearch.MVidSearch.Builder builder = BoxSearch.MVidSearch
					.newBuilder();
			builder.setAccount(req.getAcount());
			builder.setVideoid(req.getVid());
			builder.setCount(30);
			builder.setIndex(0);
			BoxSearch.MVidSearch keywordSearch = builder.build();
			dataOutput.writeInt(BoxSearch.SearchPacketType.MVidReq.getNumber());
			dataOutput.writeInt(keywordSearch.getSerializedSize());// 传输序列化的字节长度
			dataOutput.write(keywordSearch.toByteArray());// 将发送内容转换为字节码数组
			dataOutput.flush();// 清空缓存
			dataInput = new DataInputStream(socketClient.getInputStream());
			int type = dataInput.readInt();// 获取返回值的长度
			int length = dataInput.readInt();
			byte dataini[] = new byte[length];// 设置长度
			dataInput.readFully(dataini);
			dataInput.close();
			socketClient.close();
			if (type == BoxSearch.SearchPacketType.SearchErr.getNumber()) {
				BoxSearch.SearchErrPacket response = BoxSearch.SearchErrPacket
						.parseFrom(dataini);
				Log.e(TAG, "KeywordSearch=" + response.getErrMsg());
			} else {
				BoxSearch.KeywordSearchResp response = BoxSearch.KeywordSearchResp
						.parseFrom(dataini);
				if (response != null) {
					resp = new SearchKeyword();
					resp.setResultLeft(response.getResultLeft());
					ArrayList<Keyword> list = new ArrayList<Keyword>();
					for (int i = 0; i < response.getVideoCount(); i++) {
						BoxSearch.KeywordSearchResp.VideoInfo videoInfo = response
								.getVideo(i);
						Keyword v = new Keyword();
						v.setSourceType(videoInfo.getSourceType());
						v.setValue(videoInfo.getValue());
						list.add(v);
					}
					resp.setList(list);
				}
			}
		} catch (Exception e) {
			Log.e(TAG, "host:" + BinhConfig.searchHost + ","
					+ BinhConfig.SearchPort, e);
		} finally {
			closeSocket(socketClient, dataInput, dataOutput);
		}
		return resp;
	}

	/**
	 * 搜索查询
	 * 
	 * @param account
	 * @param pinyin
	 */
	public SearchPinyin PinyinSearch(SearchPinyin req) {
		Socket socketClient = null;
		SearchPinyin resp = null;
		DataOutputStream dataOutput = null;
		DataInputStream dataInput = null;
		try {
			socketClient = new Socket();
			socketClient.connect(new InetSocketAddress(BinhConfig.searchHost,
					BinhConfig.SearchPort), connTimeOut);
			socketClient.setSoTimeout(dataTimeOut);
			dataOutput = new DataOutputStream(socketClient.getOutputStream());
			BoxSearch.PinyinSearch.Builder builder = BoxSearch.PinyinSearch
					.newBuilder();
			// builder.set
			String pinyi = StrUtil.export(req.getPinyin());
			int searchtype = new Integer(0x10024);// 汉字搜索类型
			boolean hanzi = StrUtil.checkNameChese(pinyi);
			// 含有汉字字符false说明为纯英文
			Log.i(TAG, "pinyi=" + pinyi + ",hanzi=" + hanzi);
			builder.setAccount(req.getPinyin());
			builder.setIndex(req.getIndex());
			builder.setCount(req.getCount());
			builder.setPinyin(pinyi);
			BoxSearch.PinyinSearch pinyinSerch = builder.build();
			// 写数据
			if (hanzi) {
				dataOutput.writeInt(searchtype);
			} else {// 如果是汉字 则使用汉字 类型
				dataOutput.writeInt(BoxSearch.SearchPacketType.PinyinReq
						.getNumber());
			}
			dataOutput.writeInt(pinyinSerch.getSerializedSize());// 传输序列化的字节长度
			dataOutput.write(pinyinSerch.toByteArray());// 将发送内容转换为字节码数组
			dataOutput.flush();// 清空缓存
			dataInput = new DataInputStream(socketClient.getInputStream());
			int type = dataInput.readInt();// 获取返回值的长度
			int length = dataInput.readInt();
			byte dataini[] = new byte[length];// 设置长度
			dataInput.readFully(dataini);
			dataInput.close();
			socketClient.close();
			if (type == BoxSearch.SearchPacketType.SearchErr.getNumber()) {
				BoxSearch.SearchErrPacket response = BoxSearch.SearchErrPacket
						.parseFrom(dataini);
				Log.i(TAG, "KeywordSearch=" + response.getErrMsg());
				resp = new SearchPinyin();
				resp.setResultLeft(0);
				resp.setPinyin(req.getPinyin());
				resp.setList(new ArrayList<Pinyin>());
			} else {
				BoxSearch.PinyinSearchResp response = BoxSearch.PinyinSearchResp
						.parseFrom(dataini);// 将字节流转换成对象
				if (response != null) {
					resp = new SearchPinyin();
					resp.setResultLeft(response.getResultLeft());
					resp.setPinyin(response.getPinyin());
					ArrayList<Pinyin> list = new ArrayList<Pinyin>();
					for (int i = 0; i < response.getNodeCount(); i++) {
						PinyinSearchResp.Keyword keyWord = response.getNode(i);
						Pinyin vo = new Pinyin();
						vo.setSourceType(keyWord.getChannelType());
						vo.setResultCount(keyWord.getResultCount());
						vo.setResultType(keyWord.getResultType());
						vo.setChannelType(keyWord.getChannelType());
						vo.setValue(keyWord.getValue());
						vo.setVideoName(keyWord.getVideoName());
						vo.setVid(keyWord.getVid());
						list.add(vo);
					}
					resp.setList(list);
				}
			}
		} catch (Exception e) {
			Log.e(TAG, "host:" + BinhConfig.searchHost + ","
					+ BinhConfig.SearchPort, e);
		} finally {
			closeSocket(socketClient, dataInput, dataOutput);
		}
		return resp;
	}

	private void closeSocket(Socket client, DataInputStream in,
			DataOutputStream out) {
		try {
			if (in != null)
				in.close();
			if (out != null)
				out.close();
			if (client != null)
				client.close();
		} catch (IOException e) {
			Log.e(TAG, "closeSocket", e);
		}
	}
}
